package cn.jofei.common.netty.message;

import cn.jofei.common.ProxyInfo;
import cn.jofei.common.enums.Types;
import cn.jofei.common.utils.Utils;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.ZoneId;

/**
 * 消息封装
 *
 * @author Jofei Bao
 * @version learn-demo v2.0
 * @date 2022年10月21日 15:03
 */
@Data
@Accessors(chain = true)
public class Message implements Serializable, MsgType {
    /**
     * 流水号
     */
    private Integer sequenceId;
    /**
     * 消息类型  {@link MsgType}
     */
    private Integer msgType;
    /**
     * 子域名
     */
    private String subdomain;
    /**
     * 客户端注册tcp的服务端端口
     */
    private Integer port;
    /**
     * 加密码 必须
     */
    private String code;
    /**
     * 是否成功
     */
    private Boolean success;
    /**
     * 回应信息
     */
    private String msg;
    /**
     * 时间秒值
     */
    private Long time;

    /**
     * 客户端注册信息封装为 消息
     *
     * @param info
     * @return
     */
    public static Message of(ProxyInfo info) {
        Message message = new Message();
        if (Types.TCP.eq(info.getType()))
            message.msgType = TCP_REG;
        else
            message.msgType = HTTP_REG;
        message.sequenceId = Utils.sequenceId();
        message.time = LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond();
        message.subdomain = info.getSubdomain();
        message.port = info.getRemotePort();
        message.setCode(Utils.getSecret(message));
        return message;
    }

    /**
     * 客户端ping消息
     *
     * @return
     */
    public static Message ping() {
        Message message = new Message();
        message.msgType = PING;
        message.sequenceId = Utils.sequenceId();
        message.time = LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond();
        message.setCode(Utils.getSecret(message));
        return message;
    }

    /**
     * 服务端 http 提示信息
     *
     * @param subdomain
     * @return
     */
    public static Message notify(String subdomain) {
        Message message = new Message();
        message.msgType = HTTP_NOTIFY;
        message.sequenceId = Utils.sequenceId();
        message.subdomain = subdomain;
        message.time = LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond();
        message.setCode(Utils.getSecret(message));
        return message;
    }

    /**
     * 服务端 tcp 提示信息
     *
     * @param port
     * @return
     */
    public static Message notify(Integer port) {
        Message message = new Message();
        message.msgType = TCP_NOTIFY;
        message.sequenceId = Utils.sequenceId();
        message.port = port;
        message.time = LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond();
        message.setCode(Utils.getSecret(message));
        return message;
    }
    /**
     * 重新加密 必须重新调用
     *
     * @return
     */
    public Message established() {
        this.setMsgType(CONNECT_ESTABLISHED);
        this.reCode();
        return this;
    }
    /**
     * 重新加密 必须重新调用
     *
     * @return
     */
    public Message reCode() {
        this.setCode(Utils.getSecret(this));
        return this;
    }
}
